package odesimulation;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;

public class Reaction {

	public ArrayList<String> reactants; //Could be a specific class instead of String
	public ArrayList<String> products;
	//public ArrayList<String> rateModifier;
	public double reactionRate = 0.01;
	public double reverseReactionRate = 0;
	
	/**
	 * Encode the reaction reactant1+...+reactantn -> product1+...+productm
	 * The reaction is irreversible.
	 * @param reactants
	 * @param product
	 */
	public Reaction(ArrayList<String> reactants, ArrayList<String> products){
		this.reactants = reactants;
		this.products = products;
	}
	
	/**
	 * Encode the reaction reactant1+...+reactantn <-> product1+...+productm
	 * reaction can be reversible if reverseReactionRate is non zero.
	 * @param reactants
	 * @param products
	 * @param reactionRate
	 * @param reverseReactionRate
	 */
	public Reaction(ArrayList<String> reactants, ArrayList<String> products, double reactionRate, double reverseReactionRate){
		this.reactants = reactants;
		this.products = products;
		this.reactionRate = reactionRate;
		this.reverseReactionRate = reverseReactionRate;
	}
	
	public double computeFlow(String species, Map<String,Double> concentrations){
		double flow = reactionRate;
		double backflow = reverseReactionRate;
		int count = 0;
		Iterator<String> it = reactants.iterator();
		//Count how much of species is destroyed and compute the actual reaction rate
		while(it.hasNext()){
			String value = it.next();
			if(value.equals(species))
				count--;
			
			flow *= concentrations.get(value);
		}
		//Count how much of species is created and compute the actual back reaction rate
		it = products.iterator();
		while(it.hasNext()){
			String value = it.next();
			if(value.equals(species))
				count++;
			
			backflow *= concentrations.get(value);
		}
		
		return count*(flow-backflow);
	}
	
	public Reaction getReverse(){
		Reaction newReac = new Reaction(products,reactants,this.reverseReactionRate,this.reactionRate);
		return newReac;
	}
	
	public String toString(){
		String str = "";
		if(!this.reactants.isEmpty()){
			str += this.reactants.get(0);
			for(int i=1;i<this.reactants.size();i++){
				str += " + "+this.reactants.get(i);
			}
		}
		str += " -> ";
		if(!this.products.isEmpty()){
			str += this.products.get(0);
			for(int i=1;i<this.products.size();i++){
				str += " + "+this.products.get(i);
			}
		}
		return str;
	}
}
